#ifndef CLASSFILECONSTANT_H
#define CLASSFILECONSTANT_H
#include "jtypes.h"

#include <stdio.h>


enum {
  CONSTANT_Class=7, 
  CONSTANT_Fieldref=9, 
  CONSTANT_Methodref=10, 
  CONSTANT_InterfaceMethodref=11, 
  CONSTANT_String=8, 
  CONSTANT_Integer=3, 
  CONSTANT_Float=4, 
  CONSTANT_Long=5, 
  CONSTANT_Double=6, 
  CONSTANT_NameAndType=12, 
  CONSTANT_Utf8=1, 
  CONSTANT_Unicode=2
};

class ConstantPool;

struct ClassFileConstant
{
  ClassFileConstant(u1 tag,const char * descr);

  virtual void dump(ConstantPool * cp, bool complete=false) { }

  virtual void save(FILE *f) { };

  virtual u2 usedSpots() { return 1; };

  u1           tag;
  const char * descr;
};

struct ClassFileConstantString : public ClassFileConstant
{
  ClassFileConstantString(FILE *f);
  ClassFileConstantString(u2 utf8_index);

  virtual void dump(ConstantPool * cp,bool complete);

  virtual void save(FILE *f);

  u2 string_index;
};

struct ClassFileConstantClass : public ClassFileConstant
{
  ClassFileConstantClass(u2 name_index);
  ClassFileConstantClass(ConstantPool * cp,const char * classname);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  u2 name_index;
};

struct ClassFileConstantUnicode : public ClassFileConstant
{
  ClassFileConstantUnicode(u2 length,u2 * bytes);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);
  
  u2   length;
  u2 * bytes;
};

struct ClassFileConstantMethodRef : public ClassFileConstant
{
  ClassFileConstantMethodRef(u2 class_index,u2 name_and_type_index);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  u2 class_index;
  u2 name_and_type_index;
};

struct ClassFileConstantUtf8 : public ClassFileConstant
{
  ClassFileConstantUtf8(FILE *f);
  ClassFileConstantUtf8(const char * cstring);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  inline const char * getCString() { return string; };

  u2     length;
  char * string;
};

struct ClassFileConstantFieldRef : public ClassFileConstant
{
  ClassFileConstantFieldRef(FILE * f);
  ClassFileConstantFieldRef(u2 class_index, u2 name_and_type_index);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  u2 class_index;
  u2 name_and_type_index;
};

struct ClassFileConstantNameAndType : public ClassFileConstant
{
  ClassFileConstantNameAndType(FILE *f);
  ClassFileConstantNameAndType(ConstantPool * cp,
      const char * nameAndType, const char * signature);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  u2 name_index;
  u2 signature_index;
};

struct ClassFileConstantInteger : public ClassFileConstant
{
  ClassFileConstantInteger(FILE *f);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  u4 bytes;
};

struct ClassFileConstantDouble : public ClassFileConstant
{
  ClassFileConstantDouble(FILE *f);
  ClassFileConstantDouble(double);

  virtual void dump(ConstantPool * cp,bool complete);
  virtual void save(FILE *f);

  virtual u2 usedSpots() { return 2; };

  u4 low_bytes;
  u4 high_bytes;
};

#endif
